﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Input;
using UMLSynthesizer.LangAnalyzer.Elements;
using UMLSynthesizer.LangAnalyzer.ExtensionMethods;

namespace UMLSynthesizer.Tasks.ViewModel
{
    internal class ElementViewModel : ViewModelBase
    {
        #region Fields

        IElementBase element;
        bool showClasses;
        bool showMethods;
        bool showPackages;
        bool showStructs;
        Action<IElementBase> notifyElementSelection;

        ReadOnlyCollection<ElementViewModel> _childElements;
        bool _isSelected;
        
        #endregion

        #region Public interface

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="element">The element</param>
        public ElementViewModel(IElementBase element,
            Action<IElementBase> notifyElementSelection,
            bool showClasses,
            bool showMethods,
            bool showPackages,
            bool showStructs)
        {
            this.element = element;
            this.showClasses = showClasses;
            this.showMethods = showMethods;
            this.showPackages = showPackages;
            this.showStructs = showStructs;
            this.notifyElementSelection = notifyElementSelection;
        }

        #endregion

        #region Properties

        public ReadOnlyCollection<ElementViewModel> ChildElements
        {
            get
            {
                if(_childElements == null)
                    if (element as IContainerOfElementsBase == null)
                        _childElements = new List<ElementViewModel>().AsReadOnly();
                    else
                        _childElements = new List<ElementViewModel>(
                            from childElement in (element as IContainerOfElementsBase).GetChildElements()
                            where (childElement.Kind == ElementKinds.Class && showClasses) ||
                                  (childElement.Kind == ElementKinds.Method && showMethods) ||
                                  ((childElement.Kind == ElementKinds.Project ||
                                      childElement.Kind == ElementKinds.Namespace) && showPackages) ||
                                  (childElement.Kind == ElementKinds.Struct && showStructs)
                            orderby childElement.Identifier
                            select new ElementViewModel(childElement, notifyElementSelection,
                                showClasses, showMethods, showPackages, showStructs)).AsReadOnly();
                return _childElements;
            }
        }

        /// <summary>
        /// The container identifier
        /// </summary>
        public string Identifier
        { get { return element.Identifier; } }

        public string ImageUri
        {
            get
            {
                switch (element.Kind)
                {
                    case ElementKinds.Class:
                        return "/Tasks;component/Images/class.png";
                    case ElementKinds.Method:
                        return "/Tasks;component/Images/method.png";
                    case ElementKinds.Namespace:
                    case ElementKinds.Project:
                        return "/Tasks;component/Images/package.png";
                    case ElementKinds.Struct:
                        return "/Tasks;component/Images/struct.png";
                    default:
                        return "/Tasks;component/Images/empty.png";
                }
            }
        }

        /// <summary>
        /// True if this node is selected
        /// </summary>
        public bool IsSelected
        {
            get { return _isSelected; }
            set
            {
                if (value == _isSelected)
                    return;
                _isSelected = value;
                OnPropertyChanged("IsSelected");

                //call refresh event on selection
                if (notifyElementSelection != null && value)
                    notifyElementSelection(element);
            }
        }

        #endregion
    }
}
